﻿using System.Linq;
using CardPlay.Model.ActionModel;
using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;

namespace CardPlay.DemoPack.Games.FortyThievesVariants
{
    [Game("F5561533-DA40-4B11-B6AC-008C5F12C15A", LevelOfDifficulty.Medium, LevelOfSkill.MostlyChance, DurationOfPlay.MoreThan10Minutes, NumberOfDecks = 2, Family = FamilyName)]
    public class TheSpark : FortyThieves
    {
        private const string AlternateWaste = "waste.1";

        public TheSpark()
        {
            NamesOfAdditionalPiles.Add(AlternateWaste);

            CardsPerDeal = 3;
            TotalTableaus = 12;
            TableauDealFormat = "1 up";
            TableauBuildSequence = CardFaceSequence.SameSuitAscendingRank;

            FoundationBuildSequence = CardFaceSequence.SameSuitDescendingRank;
            FoundationBaseRank = Rank.King;

            DealFoundationsInSetup = true;
            PreprocessAction = AugmentDealAction;
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var metrics = presentation.Metrics;

            var root = new GridLayout
            {
                Columns = 1,
                Rows = 2,
                HorizontalContentAlignment = HorizontalAlignment.Center,
            };

            {
                var topRow = new GridLayout
                {
                    Columns = 3,
                    Rows = 1,
                };

                {
                    var stockWaste = new SideBySideLayout
                                     {
                                         presentation.CreatePileVisual(Stock, CreateStockStyle(metrics)),
                                         presentation.CreatePileVisual(Waste, presentation.StyleForWaste()),
                                         presentation.CreatePileVisual(AlternateWaste, presentation.StyleForWaste())
                                     };

                    topRow.Add(stockWaste);
                }

                {
                    topRow.Add(presentation.CreateMimimalSpacer());
                }

                {
                    var foundations = presentation.CreateRowLayout(); // CreateSideBySideLayout(metrics);

                    foreach (var name in PilesNamed(AnyFoundation).Select(pile => pile.Name))
                        foundations.Add(presentation.CreatePileVisual(name, StandardStyles.Foundation));

                    topRow.Add(foundations);
                }

                root.Add(topRow);
            }

            {
                var tableau = presentation.CreateRowLayout(); // CreateSideBySideLayout(metrics);

                foreach (var pile in PilesNamed(AnyTableau))
                    tableau.Add(presentation.CreatePileVisual(pile.Name, StandardStyles.Tableau));

                //OnTableauLayoutCreated(presentation, tableau);
                root.Add(tableau);
            }

            return root;
        }

        private IAction AugmentDealAction(IAction action)
        {
            var dealAction = action as DealAction;

            return dealAction != null
                ? new ComplexAction
                  {
                      action,
                      new DelegatingAction<string>
                      {
                          OnExecute = () => ModifyDealTarget(NameOfDealTarget == Waste ? AlternateWaste : Waste),
                          OnReverse = previousName => ModifyDealTarget(previousName)
                      }
                  }
                : action;
        }

        private string ModifyDealTarget(string name)
        {
            var nameOfPreviousTarget = NameOfDealTarget;

            NameOfDealTarget = name;
            return nameOfPreviousTarget;
        }
    }
}